package de.herberlin.htmlspecialchar;

/**
 * This class is a subject of change. Please be aware that
 * it may produce different results in future releases.
 * 
 * @author aherbertz
 */
public abstract class HTMLSpecialCharacters {

    /**
     * Encodes a string to html special chars.
     * @return the html-encoded String. */
    public static String encode(String source) {
        StringBuffer ret = new StringBuffer();
        if (source == null)
            return ret.toString();
        String t = null;
        for (int i = 0; i < source.length(); i++) {
            char ch = source.charAt(i);
            int val = (int) ch;
            if (Character.isDigit(ch)) {
                // numeric
                ret.append(ch);
			} else if (Character.isWhitespace(ch)) {
				// spaces
				ret.append(ch);
			} else if (val >= 65 && val <= 90) {
				// uppercase
				ret.append(ch);
            } else if (val >= 97 && val <= 122) {
                // lowercase
                ret.append(ch);
            } else if ((t = findReplacement(val)) != null) {
                // defined chars
                ret.append(t);
            } else {
                // append unicode html
                ret.append("&#" + val + ";");
            }
        }

        return ret.toString();
    }

    private static String findReplacement(int c) {

        String replacement = null;
        switch (c) {
			case 10: replacement="<br>"; break; // CR
			case 33: replacement="!"; break; // !
			case 34: replacement="&quot;"; break; // "
			case 38: replacement="&amp;"; break; // &
			case 40: replacement="("; break; // (
			case 41: replacement=")"; break; // )
			case 42: replacement="*"; break; // *
			case 43: replacement="+"; break; // +
			case 44: replacement=","; break; // ,
			case 45: replacement="-"; break; // -
			case 46: replacement="."; break; // .
			case 58: replacement=":"; break; // :
			case 59: replacement=";"; break; // ;
			case 60: replacement="&lt;"; break; // <
			case 61: replacement="="; break; // =
			case 62: replacement="&gt;"; break; // >
			case 63: replacement="?"; break; // ?
			case 95: replacement="_"; break; // _
			case 167: replacement="&sect;"; break; // �
			case 196: replacement="&Auml;"; break; // �
			case 214: replacement="&Ouml;"; break; // �
			case 220: replacement="&Uuml;"; break; // �
			case 223: replacement="&szlig;"; break; // �
			case 228: replacement="&auml;"; break; // �
			case 246: replacement="&ouml;"; break; // �
			case 252: replacement="&uuml;"; break; // �
			case 8364: replacement="&euro;"; break; // �
        }

        return replacement;
    }
}
